package com.wngbms;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOServer {

    public static void main(String[] args) throws IOException, InterruptedException {

        Selector selector = Selector.open();

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        // 底层调用了Listen, 已经开始监听
        serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8888), 1024);

        SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            int select = selector.select();
            System.out.print(select);
            if (select > 0) {
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                System.out.println();
                System.out.println(selectionKeys);

                process(selectionKeys);
            } else {
                Thread.sleep(600);
            }

            if (false) {
                break;
            }
        }
    }

    private static void process(Set<SelectionKey> selectionKeys) throws IOException {
        Iterator<SelectionKey> iterator = selectionKeys.iterator();
        while (iterator.hasNext()) {
            SelectionKey selectionKey = iterator.next();

            if (selectionKey.isAcceptable()) {
                ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
                Selector selector = selectionKey.selector();
                SocketChannel socketChannel = serverSocketChannel.accept();
                System.out.println(socketChannel);

                socketChannel.configureBlocking(false);
                socketChannel.register(selector, SelectionKey.OP_READ);
            } else if (selectionKey.isReadable()) {
                SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                System.out.println(socketChannel.read(buffer));
                buffer.flip();
                System.out.println(new String(buffer.array(), 0, buffer.limit()));
            }

            // 一定要remove, 否则select会不断循环(不阻塞), 导致CPU使用率飙高
//            iterator.remove();
        }
        // 可以clear掉set集合, 不用调用remove方法
        selectionKeys.clear();
    }

}
